package com.weirong.smartvault.backservice.entity_model;

import com.weirong.smartvault.common.tools.spring.context.SpringContextUtil;
import com.weirong.smartvault.backservice.util.common.ListTool;
import com.weirong.smartvault.dao.AuthorityRepository;
import com.weirong.smartvault.entity.Authority;

import java.lang.reflect.InvocationTargetException;
import java.util.*;

/**
 * Created with IntelliJ IDEA.
 * User: kfeb4
 * Date: 2017/12/28
 * Time: 11:22
 */
public class AuthorityModel {
    Authority authority;

    public boolean checked = false; // 算法用变量，一般情况无视


    public AuthorityModel(Authority authority) {
        this.authority = authority;
    }

    public Integer getGrade() {
        return authority.getGrade();
    }

    public Integer getParentId() {
        return this.authority.getParentId();
    }

    public String getUrl(){
        return authority.getUrl();
    }
    public String getRemark(){
        return authority.getRemark();
    }
    public int getId() {
        return authority.getId();
    }

    @Override
    public int hashCode() {
        return getId();
    }

    @Override
    public boolean equals(Object o) {
        if(this.hashCode()==o.hashCode())
            return true;
        return false;
    }

    public String getName() {
        return authority.getName();
    }

    static AuthorityRepository authorityRepository = SpringContextUtil.getBean(AuthorityRepository.class);
    Set<AuthorityModel> sons;

    void initSons() throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        if (sons==null){
            sons = new HashSet<>(ListTool.cast(authorityRepository.findByParentId(getId()),AuthorityModel.class));
        }
    }

    public Set<AuthorityModel> getAll() throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
        //获取所有的对象
        initSons();
        Set<AuthorityModel> res = new HashSet<>();
        res.add(this);
        for (AuthorityModel son : sons) {
            res.addAll(son.getAll());
        }
        return res;
    }

    public Set<AuthorityModel> getAllSon() throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
        initSons();
        //获取所有的子权限
        Set<AuthorityModel> res = new HashSet<>();
        for (AuthorityModel son : sons) {
            res.addAll(son.getAll());
        }
        return res;
    }

    public Set<AuthorityModel> getSons(){
        return sons;
    }
    public static List<AuthorityModel> buildTree(Collection<AuthorityModel> authorityModels) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        //获取当前权限列表所有树的跟节点
        List<AuthorityModel> res = new ArrayList<>();
        //获取第四级别
        Set<AuthorityModel> rest = new HashSet<>();
        rest.addAll(authorityModels);
        Map<Object, List<AuthorityModel>> authorityMap = ListTool.divideByKey(rest, AuthorityModel::getGrade);
        for (int i = 1; i < 10000; i++) {
            List<AuthorityModel> first = authorityMap.get(i);
            if (first.size() > 0) {
                for (AuthorityModel authorityModel : first) {
                    rest.removeAll(authorityModel.getAll());
                    res.add(authorityModel);
                }
                if (rest.size() == 0) {
                    break;
                } else {
                    //更新map
                    authorityMap = ListTool.divideByKey(rest, AuthorityModel::getGrade);
                }
            }
        }
        return res;
    }

    public AuthorityModel getParent(){
        Integer id = this.authority.getParentId();
        if (id!=null) {
            Authority authority = authorityRepository.findOne(id);
            if(authority!=null)
                return new AuthorityModel(authority);
        }
        return null;

    }
    public List<AuthorityModel> getAllParents(){
        List<AuthorityModel> res = new ArrayList<>();
        AuthorityModel parent = getParent();
        while (parent!=null) {
            res.add(parent);
            parent = parent.getParent();
        }
        return res;
    }
}
